using abilities.templates;
using abilities.triggers;
using UnityEngine;

namespace abilities.effects
{
    public abstract class Effect<T> : Effect where T : EffectTemplate
    {
        public T template { get;protected set; }
        public Effect(T t,int lv):base(t,lv)
        {
            template = t;
            InitTInternal(t as T,lv);
        }

        void InitTInternal(T t,int lv){
            OnInit(t,lv);
        }
        protected virtual void OnInit(T tpl,int lv)
        {
        }
    }
    public abstract class Effect
    {
        //***************
        
        /// 效果的等级。
        public int Level { get;protected set; }

        /// 触发器入口。
        /// 触发器可能不会马上应用或触发器可能timed后触发，某个时间或事件如onParameterChange,health < 50%时
        protected AbilityTrigger StartTrigger;

        ///当移除时触发
        protected AbilityTrigger EndTrigger;

        ///配表
        public EffectTemplate prototype { get;protected set; }

        ///剩余冷却时间
        public float CooldownLeft{ get;protected set; }

        ///动画
        protected AnimationRule animationRule;
        
        
        //***************
        
        public Effect(EffectTemplate proto,int lv)
        {
            prototype = proto;
            Level = lv;
            InitInternal(proto,Level);
        }

        void InitInternal(EffectTemplate proto,int lv)
        {
            OnInit(proto,lv);
        }

        ~Effect()
        {
            Debug.Log("~AbilityEffect %p" + this);
        }


        ///取消 
        protected abstract void Cancel(UnitObject objectView, bool replay);

        ///执行
        protected abstract void Apply(UnitObject objectView, bool replay);


        protected virtual void OnInit(EffectTemplate template, int lv)
        {
            this.animationRule = template.animationRule;
            StartTrigger = template.startTrigger != null ? template.startTrigger.CreateInstance(Level) : null;
            EndTrigger = template.endTrigger != null ? template.endTrigger.CreateInstance(Level) : null;
        }

        public void StartTriggers(AbilityContext context)
        {
            Debug.Log("startTriggers %p" + this);
            if (StartTrigger)
            {
                StartTrigger.Start(context);
            }
            else
            {
                ApplyEffect(context.AbilityManager.Owner);
            }

            if (EndTrigger)
            {
                EndTrigger.Start(context);
            }
        }

        public void ReleaseTriggers()
        {
            Debug.Log("releaseTriggers %p" + this);
            if (StartTrigger)
            {
                StartTrigger.Stop();
                StartTrigger = null;
            }

            if (EndTrigger)
            {
                EndTrigger.Stop();
                EndTrigger = null;
            }
        }

        public void StopTriggers()
        {
            if (StartTrigger)
            {
                StartTrigger.Stop();
            }

            if (EndTrigger)
            {
                EndTrigger.Stop();
            }
        }



        public void CancelEffect(UnitObject objectView)
        {
            foreach(var iter in prototype.endVfx)
            {
                //播放特效
                GameObject particle = new GameObject(iter);//ParticlesFactory.Instance.GetOne(iter);
            	if(prototype.VfsOnGround)
                {
            		particle.transform.position = objectView.transform.position;
                    
            	}
                else
                {
                    particle.transform.SetParent(objectView.transform);
            	}
            }
            //播放声音
            //SoundManager.Instance.playSound(endSound);
            //改变动画
            if (animationRule != null)
                animationRule.Cancel(objectView);
            Cancel(objectView, false);//GameMgr.Instance.IsNeedRecord()
        }

        public void ApplyEffect(UnitObject objectView)
        {
            foreach(var iter in prototype.startVfx)
            {
                //播放特效
                GameObject particle = new GameObject(iter);// ParticlesFactory.Instance.create(iter);
            	if(prototype.VfsOnGround)
                {
            		particle.transform.position = objectView.transform.position;
            	}
                else
                {
                    particle.transform.SetParent(objectView.transform);
            	}
            }
            //播放声音
            //SoundManager.Instance.playSound(startSound);
            //改变动画
            if(animationRule != null)
                animationRule.Apply(objectView);
            if(prototype.shake > 0.0f )//&& GameMgr.Instance.IsBattling())
            {
                //CameraMgr.Instance.shake(shakeFactor);
            }
            Apply(objectView, false);//GameMgr.Instance.IsNeedRecord()
        }

        public bool IsTimed => prototype.totalTime > 0 || prototype.castTime > 0;


        public void DecrementCooldown(long dt)
        {
            if (CooldownLeft > dt)
            {
                CooldownLeft -= dt;
            }
            else
            {
                CooldownLeft = 0;
            }
        }

        public void ResetCooldown()
        {
            CooldownLeft = prototype.cooldown;
        }

        public bool ActivateTriggers(AbilityTriggerType triggerType)
        {
            bool resultStartTrigger = StartTrigger ? StartTrigger.ActivateTrigger(triggerType) : false;
            if (EndTrigger)
            {
                EndTrigger.ActivateTrigger(triggerType);
            }

            return resultStartTrigger && prototype.cancelTriggering;
        }

        public void PrepareCast(UnitObject objectView, bool replay)
        {
        }
    }
}